Imports System.Drawing.Drawing2D
Imports System.ComponentModel
Imports System.ComponentModel.Design
Imports System.Windows.Forms.Design
<ToolboxItem(True), ToolboxBitmap(GetType(ColorPicker), "ColorPickerLib.ColorPicker.bmp")> _
<Designer(GetType(ColorPickerDesigner))> _
<DefaultEvent("ColorPicked")> _
Public Class ColorPicker

  Private ValueDisplay As Rectangle = New Rectangle(12, 555, 200, 25)
  Private bmpColorBar As Bitmap = New Bitmap(186, 26)
  Private bmpImg As Bitmap = New Bitmap(200, 25)
  Private bmpBrightBar As Bitmap = New Bitmap(206, 26)
  Private CurrColor As Color = Color.Red
  Private ptColorPaint As Point
  Private ptColor As Point = New Point(12, 5)
  Private szColor As Size = New Size(180, 20)
  Private ptSatPaint As Point
  Private ptSat As Point = New Point(12, 40)
  Private szSat As Size = New Size(200, 20)
  Private ptBrightPaint As Point
  Private ptBright As Point = New Point(12, 70)
  Private szBright As Size = New Size(200, 20)
  Private blnMouseDnColor As Boolean = False
  Private blnMouseDnSat As Boolean = False
  Private blnMouseDnBright As Boolean = False
  Private blnMouseDnAlpha As Boolean = False
  Private sngXColor As Single = ptColor.X
  Private sngXSat As Single = (200 + ptSat.X)
  Private sngXBright As Single = (200 + ptBright.X)
  Private sngXAlpha As Single = (200 + ValueDisplay.X)
  Private AlphaColor As Color = Color.Transparent
  Private HideCursor As Cursor
  Private blnOnHold As Boolean = True
  'List of Known Colors - Done this way because I haven't found a good
  'way to get the Known Colors in color shade order yet
  Private Known_Color() As String = Split("Transparent,Black,DimGray,Gray,DarkGray,Silver,LightGray,Gainsboro," & _
      "WhiteSmoke,White,RosyBrown,IndianRed,Brown,Firebrick,LightCoral,Maroon,DarkRed,Red,Snow,MistyRose," & _
      "Salmon,Tomato,DarkSalmon,Coral,OrangeRed,LightSalmon,Sienna,SeaShell,Chocalate,SaddleBrown,SandyBrown," & _
      "PeachPuff,Peru,Linen,Bisque,DarkOrange,BurlyWood,Tan,AntiqueWhite,NavajoWhite,BlanchedAlmond,PapayaWhip," & _
      "Mocassin,Orange,Wheat,OldLace,FloralWhite,DarkGoldenrod,Cornsilk,Gold,Khaki,LemonChiffon,PaleGoldenrod," & _
      "DarkKhaki,Beige,LightGoldenrod,Olive,Yellow,LightYellow,Ivory,OliveDrab,YellowGreen,DarkOliveGreen," & _
      "GreenYellow,Chartreuse,LawnGreen,DarkSeaGreen,ForestGreen,LimeGreen,PaleGreen,DarkGreen,Green,Lime," & _
      "Honeydew,SeaGreen,MediumSeaGreen,SpringGreen,MintCream,MediumSpringGreen,MediumAquaMarine," & _
      "YellowAquaMarine,Turquoise,LightSeaGreen,MediumTurquoise,DarkSlateGray,PaleTurquoise,Teal,DarkCyan,Aqua," & _
      "Cyan,LightCyan,Azure,DarkTurquoise,CadetBlue,PowderBlue,LightBlue,DeepSkyBlue,SkyBlue,LightSkyBlue," & _
      "SteelBlue,AliceBlue,DodgerBlue,SlateGray,LightSlateGray,LightSteelBlue,CornflowerBlue,RoyalBlue," & _
      "MidnightBlue,Lavender,Navy,DarkBlue,MediumBlue,Blue,GhostWhite,SlateBlue,DarkSlateBlue,MediumSlateBlue," & _
      "MediumPurple,BlueViolet,Indigo,DarkOrchid,DarkViolet,MediumOrchid,Thistle,Plum,Violet,Purple,DarkMagenta," & _
      "Magenta,Fuchsia,Orchid,MediumVioletRed,DeepPink,HotPink,LavenderBlush,PaleVioletRed,Crimson,Pink,LightPink", ",")

  Public Event ColorPicked(ByVal sender As Object)
  Public Event ColorChanging(ByVal sender As Object)

#Region "Initialize"

  Public Sub New()

    ' This call is required by the Windows Form Designer.
    InitializeComponent()

    ' Add any initialization after the InitializeComponent() call.
    Me.SetStyle(ControlStyles.DoubleBuffer, True)
    Me.SetStyle(ControlStyles.UserPaint, True)
    Me.SetStyle(ControlStyles.AllPaintingInWmPaint, True)
    _Value = Color.Red

    Me.nudAlpha.Font = Control.DefaultFont
    Me.nudHue.Font = Control.DefaultFont
    Me.nudSat.Font = Control.DefaultFont
    Me.nudBright.Font = Control.DefaultFont
    Me.nudRed.Font = Control.DefaultFont
    Me.nudGreen.Font = Control.DefaultFont
    Me.nudBlue.Font = Control.DefaultFont
    panSwatches2.Visible = False
    Me.panSwatches.Width = 6

  End Sub

  Private Sub ColorPicker_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    ptColorPaint = ptColor
    ptColorPaint.Offset(-3, -3)
    ptSatPaint = ptSat
    ptSatPaint.Offset(-3, -3)
    ptBrightPaint = ptBright
    ptBrightPaint.Offset(-3, -3)

    'Create the Hue Color Bar
    Dim colr As Color
    Dim g As Graphics = Graphics.FromImage(bmpColorBar)
    Dim cl As Integer = 3
    For c As Integer = 0 To 359 Step 2
      colr = HSBtoColor(c, 1, 1)
      g.DrawLine(New Pen(colr, 1), cl, 3, cl, szColor.Height + 2)
      cl += 1
    Next
    g.DrawRectangle(Pens.DarkGray, New Rectangle(0, 0, _
      szColor.Width + 5, szColor.Height + 5))

    'Create the Brightness Color Bar
    g = Graphics.FromImage(bmpBrightBar)
    Using br As LinearGradientBrush = New LinearGradientBrush(New Rectangle(2, 3, szBright.Width + 1, szBright.Height), _
      Color.Black, Color.White, LinearGradientMode.Horizontal)
      g.FillRectangle(br, New Rectangle(3, 3, szBright.Width, szBright.Height))
      g.DrawRectangle(Pens.DarkGray, New Rectangle(0, 0, szBright.Width + 5, szBright.Height + 5))
    End Using

    g.Dispose()
    blnOnHold = True

    ColorBox.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed
    AddHandler ColorBox.DrawItem, AddressOf Me.ColorBox_DrawItem
    ColorBox.Items.AddRange(Known_Color)
    ColorBox.SelectedIndex = 1


    'get the blank cursor to make the it dissapear when dragging
    Dim assem As Reflection.Assembly = Me.GetType().Assembly
    Dim my_namespace As String = assem.GetName().Name.ToString()
    Dim mystream As IO.Stream
    Try
      mystream = assem.GetManifestResourceStream(my_namespace & ".HideCursor.cur")
      HideCursor = New Cursor(mystream)

    Catch ex As Exception
      HideCursor = Cursors.Cross
    End Try
    Try
      mystream = assem.GetManifestResourceStream(my_namespace & ".Lizardsml.jpg")
      bmpImg = CType(Image.FromStream(mystream), Bitmap)
    Catch ex As Exception
      Using hb As HatchBrush = New HatchBrush(HatchStyle.Shingle, Color.Black, Color.Transparent)
        Dim bmI As Graphics = Graphics.FromImage(bmpImg)
        bmI.FillRectangle(hb, 0, 0, 210, 30)
        bmI.Dispose()
      End Using
    End Try

    AutoFlyOutToolStripMenuItem.Checked = _FlyOut

    blnOnHold = False
  End Sub

#End Region 'Initialize

#Region "Properties"

  Private _Value As Color
  <Category("Appearance ColorPicker")> _
  <Description("The current Color selected")> _
  Public Property Value() As Color
    Get
      Return _Value
    End Get
    Set(ByVal value As Color)
      UpdateHSB(value)
      UpdateRGB(value)
      nudAlpha.Value = value.A
      _Value = value
      Me.Invalidate(ValueDisplay)
      RaiseEvent ColorChanging(Me)
    End Set
  End Property

  Private _HideRGB As Boolean = False
  <Category("Appearance ColorPicker")> _
  <Description("Shows or Hides the RGB control box")> _
  Public Property HideRGB() As Boolean
    Get
      Return _HideRGB
    End Get

    Set(ByVal value As Boolean)
      _HideRGB = value
      If value = True Then
        Me.MaximumSize = New Size(266, 128)
        Me.MinimumSize = New Size(266, 128)
        Me.Width = 266
      Else
        Me.MaximumSize = New Size(370, 128)
        Me.MinimumSize = New Size(370, 128)
        Me.Width = 370
      End If
      Me.Invalidate()
    End Set
  End Property

  Enum eFlyOut
    Auto = -1
    Click = 0
  End Enum
  Private _FlyOut As eFlyOut = eFlyOut.Auto
  <Category("Appearance ColorPicker")> _
  <Description("Does the FlyOut open on MouseOver or Click")> _
  <DefaultValue(eFlyOut.Auto)> _
  Public Property FlyOut() As eFlyOut
    Get
      Return _FlyOut
    End Get
    Set(ByVal value As eFlyOut)
      _FlyOut = value
    End Set
  End Property

#End Region 'Properties

#Region "Color Helpers"
  'Special thanks to Guillaume Leparmentier for his Great article
  'Manipulating colors in .NET - Part 1  http://www.codeproject.com/KB/recipes/colorspace1.aspx
  'I used some of his RGB/HSB code here with little modification

#Region "Color Structures"

  Public Structure RGB
#Region "Fields"

    Private _Red As Integer
    Private _Green As Integer
    Private _Blue As Integer

#End Region

#Region "Operators"

    Public Shared Operator =(ByVal item1 As RGB, ByVal item2 As RGB) As Boolean
      Return item1.Red = item2.Red AndAlso _
             item1.Green = item2.Green AndAlso _
             item1.Blue = item2.Blue
    End Operator

    Public Shared Operator <>(ByVal item1 As RGB, ByVal item2 As RGB) As Boolean
      Return item1.Red <> item2.Red OrElse _
             item1.Green <> item2.Green OrElse _
             item1.Blue <> item2.Blue
    End Operator

#End Region

#Region "Accessors"

    Public Property Red()
      Get
        Return _Red
      End Get
      Set(ByVal value)
        If value > 255 Then
          _Red = 255
        Else
          If value < 0 Then
            _Red = 0
          Else
            _Red = value
          End If
        End If
      End Set
    End Property

    Public Property Green()
      Get
        Return _Green
      End Get
      Set(ByVal value)
        If value > 255 Then
          _Green = 255
        Else
          If value < 0 Then
            _Green = 0
          Else
            _Green = value
          End If
        End If
      End Set
    End Property

    Public Property Blue()
      Get
        Return _Blue
      End Get
      Set(ByVal value)
        If value > 255 Then
          _Blue = 255
        Else
          If value < 0 Then
            _Blue = 0
          Else
            _Blue = value
          End If
        End If
      End Set
    End Property

#End Region

    ' Creates an instance of a RGB structure.
    Public Sub New(ByVal r As Integer, ByVal g As Integer, ByVal b As Integer)
      Me.Red = r
      Me.Green = g
      Me.Blue = b
    End Sub

#Region "Methods"

    Public Overrides Function Equals(ByVal obj As Object) As Boolean
      If (obj Is Nothing) Or (Me.GetType() IsNot obj.GetType()) Then Return False
      Return (Me = CType(obj, RGB))
    End Function

    Public Overrides Function GetHashCode() As Integer
      Return Red.GetHashCode() ^ Green.GetHashCode() ^ Blue.GetHashCode()
    End Function

#End Region

  End Structure

  Public Structure HSB

#Region "Fields"

    Private _Hue As Double
    Private _Saturation As Double
    Private _Brightness As Double

#End Region

#Region "Operators"

    Public Shared Operator =(ByVal item1 As HSB, ByVal item2 As HSB) As Boolean
      Return item1.Hue = item2.Hue AndAlso _
             item1.Saturation = item2.Saturation AndAlso _
             item1.Brightness = item2.Brightness
    End Operator

    Public Shared Operator <>(ByVal item1 As HSB, ByVal item2 As HSB) As Boolean
      Return item1.Hue <> item2.Hue OrElse _
             item1.Saturation <> item2.Saturation OrElse _
             item1.Brightness <> item2.Brightness
    End Operator

#End Region

#Region "Accessors"

    Public Property Hue()
      Get
        Return _Hue
      End Get
      Set(ByVal value)
        If value > 360 Then
          _Hue = 360
        Else
          If value < 0 Then
            _Hue = 0
          Else
            _Hue = value
          End If
        End If
      End Set
    End Property

    Public Property Saturation()
      Get
        Return _Saturation
      End Get
      Set(ByVal value)
        If value > 1 Then
          _Saturation = 1
        Else
          If value < 0 Then
            _Saturation = 0
          Else
            _Saturation = value
          End If
        End If
      End Set
    End Property

    Public Property Brightness()
      Get
        Return _Brightness
      End Get
      Set(ByVal value)
        If value > 1 Then
          _Brightness = 1
        Else
          If value < 0 Then
            _Brightness = 0
          Else
            _Brightness = value
          End If
        End If
      End Set
    End Property

#End Region

    ' Creates an instance of a HSB structure.
    Public Sub New(ByVal h As Double, ByVal s As Double, ByVal b As Double)
      Me.Hue = h
      Me.Saturation = s
      Me.Brightness = b
    End Sub

#Region "Methods"

    Public Overrides Function Equals(ByVal obj As Object) As Boolean
      If (obj Is Nothing) Or (Me.GetType() IsNot obj.GetType()) Then Return False
      Return (Me = CType(obj, HSB))
    End Function

    Public Overrides Function GetHashCode() As Integer
      Return Hue.GetHashCode() ^ Saturation.GetHashCode() ^ Brightness.GetHashCode()
    End Function

#End Region

  End Structure

#End Region 'Color Structures

#Region "RGBtoHSB"

  ' Converts RGB to a HSB.
  Public Shared Function RGBtoHSB(ByVal red As Integer, ByVal green As Integer, ByVal blue As Integer) As HSB

    Dim h As Double = 0.0
    Dim s As Double = 0.0

    ' normalizes red-green-blue values
    Dim nRed As Double = CDbl(red) / 255.0
    Dim nGreen As Double = CDbl(green) / 255.0
    Dim nBlue As Double = CDbl(blue) / 255.0

    Dim max As Double = Math.Max(nRed, Math.Max(nGreen, nBlue))
    Dim min As Double = Math.Min(nRed, Math.Min(nGreen, nBlue))

    ' Hue
    If (max = nRed) And (nGreen >= nBlue) Then
      If (max - min = 0) Then
        h = 0.0
      Else
        h = 60 * (nGreen - nBlue) / (max - min)
      End If
    ElseIf (max = nRed) And (nGreen < nBlue) Then
      h = 60 * (nGreen - nBlue) / (max - min) + 360
    ElseIf (max = nGreen) Then
      h = 60 * (nBlue - nRed) / (max - min) + 120
    ElseIf (max = nBlue) Then
      h = 60 * (nRed - nGreen) / (max - min) + 240
    End If

    If h > 359 Then h = 359

    ' Saturation
    If (max = 0) Then
      s = 0.0
    Else
      s = 1.0 - (min / max)
    End If

    Return New HSB(h, s, max)

  End Function

#End Region 'RGBtoHSB

#Region "HSBtoRGB"

  ' Converts HSB to RGB.
  Public Shared Function HSBtoRGB(ByVal HSB As HSB) As RGB
    Return HSBtoRGB(HSB.Hue, HSB.Saturation, HSB.Brightness)
  End Function

  ' Converts HSB to RGB.
  Public Shared Function HSBtoRGB(ByVal h As Integer, ByVal s As Integer, ByVal b As Integer) As RGB
    Return HSBtoRGB(CDbl(h), CDbl(s / 100.0), CDbl(b / 100.0))
  End Function

  ' Converts HSB to a RGB.
  Public Shared Function HSBtoRGB(ByVal h As Double, ByVal s As Double, ByVal b As Double) As RGB

    Dim red As Double = 0.0
    Dim green As Double = 0.0
    Dim blue As Double = 0.0

    If (s = 0) Then

      red = b
      green = b
      blue = b

    Else

      ' the color wheel consists of 6 sectors. Figure out which sector you're in.
      Dim sectorPos As Double = h / 60.0
      Dim sectorNumber As Integer = CInt(Math.Floor(sectorPos))
      ' get the fractional part of the sector
      Dim fractionalSector As Double = sectorPos - sectorNumber

      ' calculate values for the three axes of the color. 
      Dim p As Double = b * (1.0 - s)
      Dim q As Double = b * (1.0 - (s * fractionalSector))
      Dim t As Double = b * (1.0 - (s * (1 - fractionalSector)))

      ' assign the fractional colors to r, g, and b based on the sector the angle is in.
      Select Case sectorNumber
        Case 0
          red = b
          green = t
          blue = p
        Case 1
          red = q
          green = b
          blue = p
        Case 2
          red = p
          green = b
          blue = t
        Case 3
          red = p
          green = q
          blue = b
        Case 4
          red = t
          green = p
          blue = b
        Case 5
          red = b
          green = p
          blue = q
      End Select

    End If

    'Return New RGB(cint((Math.Ceiling(T(0) * 255.0)), _
    '               cint((Math.Ceiling(T(1) * 255.0)), _
    '               cint((Math.Ceiling(T(2) * 255.0)))

    Return New RGB(CInt(Double.Parse(String.Format("{0:0.00}", red * 255.0))), _
                   CInt(Double.Parse(String.Format("{0:0.00}", green * 255.0))), _
                   CInt(Double.Parse(String.Format("{0:0.00}", blue * 255.0))))


  End Function

#End Region 'HSBtoRGB

#Region "HSBtoColor"

  ' Converts HSB to .Net Color.
  Public Shared Function HSBtoColor(ByVal HSB As HSB) As Color
    Return HSBtoColor(HSB.Hue, HSB.Saturation, HSB.Brightness)
  End Function

  ' Converts HSB to a .Net Color.
  Public Shared Function HSBtoColor(ByVal h As Double, ByVal s As Double, ByVal b As Double) As Color
    Dim rgb As RGB = HSBtoRGB(h, s, b)
    Return Color.FromArgb(rgb.Red, rgb.Green, rgb.Blue)
  End Function

#End Region 'HSBtoColor

#End Region 'Color Helpers

#Region "Mouse Events"

  Private Sub ColorPicker_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown
    If e.Button = Windows.Forms.MouseButtons.Left Then
      If ValueDisplay.Contains(e.Location) Then
        UpdateColor()
        RaiseEvent ColorPicked(Me)
      Else
        If New Rectangle(ptColor, szColor).Contains(e.Location) Then
          Me.Cursor = HideCursor
          blnMouseDnColor = True
          UpdateColorBar(e.X)
          nudHue.Value = (sngXColor - ptColor.X) * 2
          panHueSwatch.BackColor = HSBtoColor(nudHue.Value, 1, 1)
        ElseIf New Rectangle(ptSat, szSat).Contains(e.Location) Then
          Me.Cursor = HideCursor
          blnMouseDnSat = True
          UpdateSatBar(e.X)
          nudSat.Value = (sngXSat - ptSat.X) / 2

        ElseIf New Rectangle(ptBright, szBright).Contains(e.Location) Then
          Me.Cursor = HideCursor
          blnMouseDnBright = True
          UpdateBrightBar(e.X)
          nudBright.Value = (sngXBright - ptBright.X) / 2

        ElseIf IsMouseOverAlpha(e.X, e.Y) Then
          blnMouseDnAlpha = True
          Dim rect As Rectangle = GetAlphaRect(sngXAlpha)
          rect.Inflate(2, 2)
          Me.Invalidate(rect)
        End If
        UpdateColor()
      End If

    End If
  End Sub

  Private Sub ColorPicker_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove

    If blnMouseDnAlpha Then
      UpdateAlpha(e.X)
      nudAlpha.Value = (sngXAlpha - ValueDisplay.X) / (ValueDisplay.Width / 255)
      UpdateColor()
    Else
      If IsMouseOverAlpha(e.X, e.Y) Then
        AlphaColor = Color.FromArgb(255, _Value.R, _Value.G, _Value.B)
        Me.Invalidate(GetAlphaRect(sngXAlpha))
      Else
        AlphaColor = Color.Transparent
        Me.Invalidate(GetAlphaRect(sngXAlpha))
      End If
    End If

    If ValueDisplay.Contains(e.Location) Then
      Me.Cursor = Cursors.Hand
    Else
      Me.Cursor = Cursors.Default
    End If

    If blnMouseDnColor Then
      If New Rectangle(ptColor, szColor).Contains(e.Location) Then
        Cursor = HideCursor
        UpdateColorBar(e.X)
        nudHue.Value = (sngXColor - ptColor.X) * 2
        panHueSwatch.BackColor = HSBtoColor(nudHue.Value, 1, 1)
      Else
        Cursor = Cursors.Default
        panHueSwatch.BackColor = SystemColors.Control
      End If
      UpdateColor()
    End If

    If blnMouseDnSat Then
      If New Rectangle(ptSat, szSat).Contains(e.Location) Then
        Cursor = HideCursor
        UpdateSatBar(e.X)
        nudSat.Value = (sngXSat - ptSat.X) / 2
      End If
      UpdateColor()
    End If

    If blnMouseDnBright Then
      If New Rectangle(ptBright, szBright).Contains(e.Location) Then
        Cursor = HideCursor
        UpdateBrightBar(e.X)
        nudBright.Value = (sngXBright - ptBright.X) / 2
      End If
      UpdateColor()
    End If

  End Sub

  Private Sub ColorPicker_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseUp
    Cursor = Cursors.Default

    If blnMouseDnColor Then
      Me.Invalidate(New Rectangle(ptSat.X - 4, ptSat.Y - 4, szSat.Width + 8, szSat.Height + 8))
    End If
    blnMouseDnColor = False
    blnMouseDnSat = False
    blnMouseDnBright = False
    blnMouseDnAlpha = False
  End Sub

  Private Function IsMouseOverAlpha(ByVal X As Integer, ByVal Y As Integer) As Boolean
    'Convert to Region.
    Using PointerRegion As New Region(GetAlphaPath(sngXAlpha))
      'Is the point inside the region.
      Return PointerRegion.IsVisible(X, Y)
    End Using
  End Function

#End Region 'Mouse Events

#Region "Drawing"

  Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
    MyBase.OnPaint(e)
    'create canvas to eliminate flicker
    Dim bmp As Bitmap = New Bitmap(Me.Width, Me.Height)
    Dim g As Graphics = Graphics.FromImage(bmp)

    'Draw Color Value
    g.FillRectangle(New TextureBrush(bmpImg, WrapMode.Tile), ValueDisplay)
    g.FillRectangle(New SolidBrush(Color.FromArgb(nudAlpha.Value, _Value)), ValueDisplay)

    'Draw a rectangle around the ValueDisplay
    g.DrawRectangle(Pens.DarkGray, ValueDisplay.Location.X - 3, _
        ValueDisplay.Location.Y - 3, ValueDisplay.Width + 5, ValueDisplay.Height + 5)

    'Draw the Alpha Pointer
    'g.FillPath(New SolidBrush(AlphaColor), GetAlphaPath(sngXAlpha))
    'g.DrawPath(Pens.Blue, GetAlphaPath(sngXAlpha))

    'Draw Hue Color Bar
    g.DrawImage(bmpColorBar, ptColorPaint)
    DrawSelector(g, New Rectangle(ptColor, szColor), sngXColor, panHueSwatch.BackColor)

    'Draw Saturation Color Bar
    Using br As LinearGradientBrush = New LinearGradientBrush _
      (New Rectangle(ptSatPaint.X + 3, ptSatPaint.Y + 3, _
      szSat.Width, szSat.Height), Color.White, CurrColor, LinearGradientMode.Horizontal)
      g.FillRectangle(br, New Rectangle(ptSatPaint.X + 3, ptSatPaint.Y + 3, szSat.Width, szSat.Height))
      g.DrawRectangle(Pens.DarkGray, _
          New Rectangle(ptSatPaint.X, ptSatPaint.Y, szSat.Width + 5, szSat.Height + 5))
    End Using

    'DrawSelector
    DrawSelector(g, New Rectangle(ptSat, szSat), sngXSat, HSBtoColor(nudHue.Value, nudSat.Value / 100, 1))

    'Draw Brightness Color Bar
    g.DrawImage(bmpBrightBar.Clone, ptBrightPaint)
    DrawSelector(g, New Rectangle(ptBright, szBright), sngXBright, HSBtoColor(0, 0, nudBright.Value / 100))

    'Paint everything to the control
    e.Graphics.DrawImage(bmp.Clone, 0, 0)
    bmp.Dispose()
    g.Dispose()
  End Sub

  Private Sub UpdateColor()
    Value = Color.FromArgb(nudAlpha.Value, HSBtoColor(nudHue.Value, nudSat.Value / 100, nudBright.Value / 100))
  End Sub

  Private Sub UpdateColorBar(ByVal xPos As Integer)
    InvalSelector(sngXColor, xPos, ptColor, szColor)
    If sngXColor > 179.5 + ptColor.X Then sngXColor = 179.5 + ptColor.X
    CurrColor = HSBtoColor((sngXColor - ptColor.X) * 2, 1, 1)
  End Sub

  Private Sub UpdateSatBar(ByVal xPos As Integer)
    InvalSelector(sngXSat, xPos, ptSat, szSat)
  End Sub

  Private Sub UpdateBrightBar(ByVal xPos As Integer)
    InvalSelector(sngXBright, xPos, ptBright, szBright)
  End Sub

  Private Sub InvalSelector(ByRef xPos1 As Integer, ByVal xPos2 As Integer, ByVal pt As Point, ByVal sz As Size)
    'Invalidate the old selector position, Check the current position, and Invalidate the new selector
    Me.Invalidate(New Rectangle(xPos1 - 3, pt.Y - 5, 6, 5))
    Me.Invalidate(New Rectangle(xPos1, pt.Y, 1, sz.Height))
    Me.Invalidate(New Rectangle(xPos1 - 3, pt.Y + sz.Height, 6, 5))
    If xPos2 < pt.X Then xPos2 = pt.X
    If xPos2 > pt.X + sz.Width Then xPos2 = pt.X + sz.Width
    xPos1 = xPos2
    Me.Invalidate(New Rectangle(xPos2 - 4, pt.Y - 5, 8, 5))
    Me.Invalidate(New Rectangle(xPos2, pt.Y, 1, sz.Height))
    Me.Invalidate(New Rectangle(xPos2 - 4, pt.Y + sz.Height, 8, 5))
  End Sub

  Private Sub DrawSelector(ByRef g As Graphics, ByRef rect As Rectangle, ByVal xPos As Integer, ByVal fill As Color)
    g.DrawLine(Pens.White, xPos, rect.Top, xPos, rect.Bottom)
    g.FillEllipse(New SolidBrush(fill), xPos - 2, rect.Top - 5, 4, 4)
    g.DrawEllipse(Pens.Black, xPos - 2, rect.Top - 5, 4, 4)
    g.FillEllipse(New SolidBrush(fill), xPos - 2, rect.Bottom, 4, 4)
    g.DrawEllipse(Pens.Black, xPos - 2, rect.Bottom, 4, 4)
  End Sub

  Private Sub UpdateAlpha(ByVal xPos As Integer)
    Dim rect As Rectangle = GetAlphaRect(sngXAlpha)
    rect.Inflate(10, 10)
    rect.Offset(-5, -5)
    Me.Invalidate(rect)
    sngXAlpha = xPos
    If sngXAlpha - ValueDisplay.X < 0 Then sngXAlpha = ValueDisplay.X
    If sngXAlpha - ValueDisplay.X > 200 Then sngXAlpha = 200 + ValueDisplay.X
    Me.Invalidate(rect)
  End Sub

  Private Function GetAlphaRect(ByVal xPos As Integer) As Rectangle
    Return New Rectangle(xPos - 5, ValueDisplay.Bottom, 10, 8)
  End Function

  Private Function GetAlphaPath(ByVal xPos As Integer) As GraphicsPath
    Dim rect As RectangleF = GetAlphaRect(xPos)
    Dim gp As New GraphicsPath
    gp.AddLine(rect.X + (rect.Width / 2), rect.Y, rect.X + rect.Width, rect.Y + rect.Height)
    gp.AddLine(rect.X + rect.Width, rect.Y + rect.Height, rect.X, rect.Y + rect.Height)
    gp.AddLine(rect.X, rect.Y + rect.Height, rect.X + (rect.Width / 2), rect.Y)
    gp.CloseFigure()
    Return gp
  End Function


#End Region 'Drawing

#Region "Control Events"

  Private Sub UpdateRGB(ByVal c As Color)
    nudRed.Value = c.R
    nudGreen.Value = c.G
    nudBlue.Value = c.B
    tbarRed.Value = nudRed.Value
    tbarGreen.Value = nudGreen.Value
    tbarBlue.Value = nudBlue.Value
  End Sub

  Private Sub UpdateHSB(ByVal c As Color)
    Dim cHSB As HSB = RGBtoHSB(c.R, c.G, c.B)
    nudHue.Value = cHSB.Hue
    nudSat.Value = cHSB.Saturation * 100
    nudBright.Value = cHSB.Brightness * 100
    Me.Invalidate(New Rectangle(ptSat.X - 4, ptSat.Y - 4, szSat.Width + 8, szSat.Height + 8))
  End Sub

  Private Sub ColorBox_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ColorBox.SelectedIndexChanged
    If Not blnOnHold Then
      UpdateRGB(Color.FromName(ColorBox.Text))
      UpdateHSB(Color.FromName(ColorBox.Text))
      panSwatches.Width = 6
      panSwatches.BorderStyle = Windows.Forms.BorderStyle.None
      panSwatches2.Visible = False
    End If
  End Sub

  Private Sub ColorPanels_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
      Handles Panel4.Click, Panel7.Click, Panel8.Click, Panel9.Click, Panel10.Click, Panel11.Click, _
      Panel12.Click, Panel13.Click, Panel20.Click, Panel19.Click, Panel14.Click, Panel15.Click, Panel16.Click, _
      Panel17.Click, Panel21.Click, Panel18.Click, Panel28.Click, Panel27.Click, Panel26.Click, Panel25.Click, _
      Panel24.Click, Panel23.Click, Panel6.Click, Panel29.Click, Panel5.Click, Panel48.Click, Panel47.Click, _
      Panel46.Click, Panel45.Click, Panel44.Click, Panel43.Click, Panel42.Click, Panel41.Click, Panel40.Click, _
      Panel22.Click, Panel39.Click, Panel38.Click, Panel37.Click, Panel36.Click, Panel35.Click, Panel34.Click, _
      Panel33.Click, Panel32.Click, Panel31.Click, Panel30.Click, Panel3.Click, Panel2.Click, Panel1.Click
    UpdateRGB(sender.backcolor)
    UpdateHSB(sender.backcolor)
    panSwatches.Width = 6
    panSwatches.BorderStyle = Windows.Forms.BorderStyle.None
    panSwatches2.Visible = False
  End Sub

  Private CurrSwatch As Panel
  Private Sub ColorPanels_MouseEnter(ByVal sender As Object, ByVal e As System.EventArgs) _
      Handles Panel5.MouseEnter, Panel7.MouseEnter, Panel8.MouseEnter, Panel9.MouseEnter, Panel3.MouseEnter, Panel11.MouseEnter, _
      Panel12.MouseEnter, Panel13.MouseEnter, Panel20.MouseEnter, Panel19.MouseEnter, Panel14.MouseEnter, Panel15.MouseEnter, _
       Panel16.MouseEnter, Panel17.MouseEnter, Panel21.MouseEnter, Panel18.MouseEnter, Panel28.MouseEnter, Panel27.MouseEnter, _
       Panel26.MouseEnter, Panel25.MouseEnter, Panel24.MouseEnter, Panel23.MouseEnter, Panel6.MouseEnter, Panel29.MouseEnter, _
       Panel22.MouseEnter, Panel48.MouseEnter, Panel47.MouseEnter, Panel46.MouseEnter, Panel45.MouseEnter, Panel44.MouseEnter, _
       Panel43.MouseEnter, Panel42.MouseEnter, Panel41.MouseEnter, Panel40.MouseEnter, Panel4.MouseEnter, Panel39.MouseEnter, _
       Panel38.MouseEnter, Panel37.MouseEnter, Panel36.MouseEnter, Panel35.MouseEnter, Panel34.MouseEnter, Panel33.MouseEnter, _
       Panel32.MouseEnter, Panel31.MouseEnter, Panel30.MouseEnter, Panel10.MouseEnter, Panel2.MouseEnter, Panel1.MouseEnter

    Try
      CurrSwatch.BorderStyle = Windows.Forms.BorderStyle.Fixed3D
    Catch ex As Exception
    End Try
    CurrSwatch = sender
    CurrSwatch.BorderStyle = Windows.Forms.BorderStyle.FixedSingle
  End Sub

  Private Sub nudHue_ValueChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles nudHue.ValueChanged
    If Not blnMouseDnColor Then
      blnOnHold = True
      UpdateColorBar(((nudHue.Value / 2) + ptColor.X))
      Me.Invalidate(New Rectangle(ptSat.X - 4, ptSat.Y - 4, szSat.Width + 8, szSat.Height + 8))
      panHueSwatch.BackColor = HSBtoColor(nudHue.Value, 1, 1)
      UpdateColor()
      blnOnHold = False
    End If
  End Sub

  Private Sub nudSat_ValueChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles nudSat.ValueChanged
    If Not blnMouseDnSat Then
      blnOnHold = True
      UpdateSatBar(((nudSat.Value) * 2) + ptSat.X)
      UpdateColor()
      blnOnHold = False
    End If
  End Sub

  Private Sub nudBright_ValueChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles nudBright.ValueChanged
    If Not blnMouseDnBright Then
      blnOnHold = True
      UpdateBrightBar(((nudBright.Value) * 2) + ptBright.X)
      UpdateColor()
      blnOnHold = False
    End If
  End Sub

  Private Sub nudAlpha_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles nudAlpha.ValueChanged
    If Not blnMouseDnAlpha Then
      UpdateAlpha((nudAlpha.Value + ValueDisplay.X) * (ValueDisplay.Width / 255))
    End If
    Dim rect As Rectangle = GetAlphaRect(sngXAlpha)
    rect.Inflate(10, 10)
    rect.Offset(-5, -5)
    Me.Invalidate(rect)
    Me.Invalidate(ValueDisplay)

  End Sub

  Private Sub tbar_Scroll(ByVal sender As System.Object, ByVal e As System.EventArgs) _
      Handles tbarRed.Scroll, tbarGreen.Scroll, tbarBlue.Scroll
    nudRed.Value = tbarRed.Value
    nudGreen.Value = tbarGreen.Value
    nudBlue.Value = tbarBlue.Value

    If Not blnOnHold AndAlso Not blnMouseDnColor AndAlso Not blnMouseDnBright AndAlso Not blnMouseDnSat Then
      blnOnHold = True
      UpdateHSB(Color.FromArgb(nudRed.Value, nudGreen.Value, nudBlue.Value))
      blnOnHold = False
    End If
  End Sub

  Private Sub nudRGB_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) _
      Handles nudRed.ValueChanged, nudGreen.ValueChanged, nudBlue.ValueChanged
    tbarRed.Value = nudRed.Value
    tbarGreen.Value = nudGreen.Value
    tbarBlue.Value = nudBlue.Value

    If Not blnOnHold AndAlso Not blnMouseDnColor AndAlso Not blnMouseDnBright AndAlso Not blnMouseDnSat Then
      blnOnHold = True
      UpdateHSB(Color.FromArgb(nudRed.Value, nudGreen.Value, nudBlue.Value))
      blnOnHold = False
    End If
  End Sub

  Private Sub panSwatches_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
      Handles panSwatches.Click
    If _FlyOut = eFlyOut.Click And panSwatches.Width = 6 Then
      OpenSwatchPanel()
    End If
  End Sub

  Private Sub panSwatches_MouseEnter(ByVal sender As Object, ByVal e As System.EventArgs) Handles panSwatches.MouseEnter
    If _FlyOut = eFlyOut.Auto And panSwatches.Width = 6 Then
      OpenSwatchPanel()
    End If

  End Sub

  Private Sub OpenSwatchPanel()
    panSwatches2.Visible = True
    panSwatches.Width = 217
    panSwatches.BorderStyle = Windows.Forms.BorderStyle.FixedSingle
  End Sub

  Private Sub CloseSwatchPanel()
    panSwatches.Width = 6
    panSwatches2.Visible = False
    panSwatches.BorderStyle = Windows.Forms.BorderStyle.None

  End Sub

  Private Sub butSwatchClose_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
      Handles butSwatchClose.Click
    CloseSwatchPanel()
  End Sub

  Private Sub panSwatches_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles panSwatches.Paint
    If panSwatches.Width = 6 Then

      Dim g As Graphics = panSwatches.CreateGraphics
      g.SmoothingMode = SmoothingMode.AntiAlias
      Dim gp As New GraphicsPath
      Dim rect As Rectangle = New Rectangle(0, 0, panSwatches.Width, panSwatches.Height)
      Using lgbr As LinearGradientBrush = New LinearGradientBrush(rect, Color.DarkBlue, Color.Transparent, LinearGradientMode.Horizontal)
        g.FillRectangle(lgbr, rect)
      End Using
      Dim pts() As Point = New Point() { _
          New Point(0, (panSwatches.Height / 2) - 5), _
          New Point(5, (panSwatches.Height / 2)), _
          New Point(0, (panSwatches.Height / 2) + 6) _
          }
      g.FillPolygon(Brushes.White, pts)
      g.DrawPolygon(Pens.DarkBlue, pts)
      g.Dispose()
      gp.Dispose()
    End If
  End Sub

  Private Sub butSwatchClose_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles butSwatchClose.Paint
    e.Graphics.DrawString("X", butSwatchClose.Font, Brushes.White, 2, 1)
  End Sub

  Private Sub AutoFlyOutToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AutoFlyOutToolStripMenuItem.Click
    AutoFlyOutToolStripMenuItem.Checked = Not AutoFlyOutToolStripMenuItem.Checked
    _FlyOut = AutoFlyOutToolStripMenuItem.Checked
  End Sub
#End Region

#Region "ColorBox"

  Private Sub ColorBox_DrawItem(ByVal sender As Object, _
      ByVal e As DrawItemEventArgs)

    If (e.State And DrawItemState.Selected) = DrawItemState.Selected Then
      e.Graphics.FillRectangle(Brushes.CornflowerBlue, e.Bounds)
    Else
      e.Graphics.FillRectangle(Brushes.White, e.Bounds)
    End If

    Dim itemString As String = CType(sender.Items(e.Index), String)
    Dim MyFont = New Font("Microsoft Sans Serif", 8.25)
    Dim myBrush As New SolidBrush(Color.FromName(itemString))

    'Draw a Color Swatch
    e.Graphics.FillRectangle(myBrush, e.Bounds.X + 3, e.Bounds.Y + 2, 20, e.Bounds.Height - 5)
    e.Graphics.DrawRectangle(Pens.Black, e.Bounds.X + 3, e.Bounds.Y + 2, 20, e.Bounds.Height - 5)

    ' Draw the text in the item.
    e.Graphics.DrawString(itemString, MyFont, _
        Brushes.Black, e.Bounds.X + 25, e.Bounds.Y + 1)

    ' Draw the focus rectangle around the selected item.
    e.DrawFocusRectangle()
    myBrush.Dispose()
  End Sub

#End Region 'ColorBox

#Region "EyeDropper Events"

  Private Sub EyeDropper1_SelectedColorChanged(ByVal sender As System.Object, ByVal CurrColor As System.Drawing.Color) Handles EyeDropper1.SelectedColorChanged
    Me.Value = CurrColor
    CloseSwatchPanel()
  End Sub

  Private Sub EyeDropper1_SelectedColorChanging(ByVal sender As Object, ByVal CurrColor As System.Drawing.Color) Handles EyeDropper1.SelectedColorChanging
    panEyedropper.BackColor = CurrColor
  End Sub

#End Region 'EyeDropper Events

End Class

#Region "ColorPickerDesigner"

Public Class ColorPickerDesigner

  Inherits ControlDesigner

#Region "ActionLists"

  Private _Lists As DesignerActionListCollection

  Public Overrides ReadOnly Property ActionLists() As System.ComponentModel.Design.DesignerActionListCollection
    Get
      If _Lists Is Nothing Then
        _Lists = New DesignerActionListCollection
        _Lists.Add(New ColorPickerActionList(Me.Component))
      End If
      Return _Lists
    End Get
  End Property

#End Region 'ActionLists

End Class

#Region "ColorPickerActionList"

Public Class ColorPickerActionList
  Inherits DesignerActionList

  Private _ColorPickerSelector As ColorPicker
  Private _DesignerService As DesignerActionUIService = Nothing

  Public Sub New(ByVal component As IComponent)
    MyBase.New(component)

    ' Save a reference to the control we are designing.
    _ColorPickerSelector = DirectCast(component, ColorPicker)

    ' Save a reference to the DesignerActionUIService
    _DesignerService = _
        CType(GetService(GetType(DesignerActionUIService)),  _
        DesignerActionUIService)

    'Makes the Smart Tags open automatically 
    Me.AutoShow = True
  End Sub

#Region "Smart Tag Items"

#Region "Properties"

  Public Property Value() As Color
    Get
      Return _ColorPickerSelector.Value
    End Get
    Set(ByVal value As Color)
      SetControlProperty("Value", value)
    End Set
  End Property

  Public Property BackColor() As Color
    Get
      Return _ColorPickerSelector.BackColor
    End Get
    Set(ByVal value As Color)
      SetControlProperty("BackColor", value)
    End Set
  End Property

  Public Property HideRGB() As Boolean
    Get
      Return _ColorPickerSelector.HideRGB
    End Get
    Set(ByVal value As Boolean)
      SetControlProperty("HideRGB", value)
      _DesignerService.Refresh(_ColorPickerSelector)

    End Set
  End Property

  Public Property FlyOut() As ColorPicker.eFlyOut
    Get
      Return _ColorPickerSelector.FlyOut
    End Get
    Set(ByVal value As ColorPicker.eFlyOut)
      SetControlProperty("FlyOut", value)
    End Set
  End Property

#End Region 'Properties

  ' Set a control property. This method makes Undo/Redo
  ' work properly and marks the form as modified in the IDE.
  Private Sub SetControlProperty(ByVal property_name As String, ByVal value As Object)
    TypeDescriptor.GetProperties(_ColorPickerSelector) _
        (property_name).SetValue(_ColorPickerSelector, value)
  End Sub

#End Region ' Smart Tag Items

  ' Return the smart tag action items.
  Public Overrides Function GetSortedActionItems() As System.ComponentModel.Design.DesignerActionItemCollection
    Dim items As New DesignerActionItemCollection()

    items.Add( _
        New DesignerActionPropertyItem( _
            "HideRGB", _
            "Hide RGB Panel", _
            "Color Picker", _
            "Show or Hide RGB Panel"))
    items.Add( _
        New DesignerActionPropertyItem( _
            "FlyOut", _
            "Auto Color Flyout", _
            "Color Picker", _
            "Show FlyOut Automatically or with a MouseClick"))
    items.Add( _
        New DesignerActionPropertyItem( _
            "BackColor", _
            "Background Color", _
            "Color Picker", _
            "The Background Color of the Control"))

    items.Add( _
        New DesignerActionHeaderItem("Value"))
    items.Add( _
        New DesignerActionPropertyItem( _
            "Value", _
            "Current Value", _
            "Selected Color Value", _
            "The color currently selected"))

    'Add Text Item 
    items.Add( _
        New DesignerActionTextItem( _
            Space(28) & "Gonzo Diver", _
            " "))
    Return items
  End Function

End Class

#End Region 'DDPActionList

#End Region 'ColorPickerDesigner

#Region "EyeDropper"

<ToolboxItem(True), ToolboxBitmap(GetType(EyeDropper), "ColorPickerLib.EyeDropper.bmp")> _
<DefaultEvent("SelectedColorChanged")> _
 Public Class EyeDropper
  Inherits UserControl

  Public Event SelectedColorChanging(ByVal sender As Object, ByVal CurrColor As Color)
  Public Event SelectedColorChanged(ByVal sender As Object, ByVal CurrColor As Color)

  Private szDownSize As Size = New Size(23, 23)
  Private bmpScreenShot As Bitmap
  Private DropperCursor As Cursor
  Private sngZoom As Single = 5
  Private blnGettingPixelColor As Boolean = False
  Private szZoomWindowSize As Size = New Size(100, 100)
  Private bmpButtonImage As Bitmap

#Region "Initialize"

  Public Sub New()

    ' This call is required by the Windows Form Designer.
    'InitializeComponent()

    ' Add any initialization after the InitializeComponent() call.
    Me.SetStyle(ControlStyles.DoubleBuffer, True)
    Me.SetStyle(ControlStyles.UserPaint, True)
    Me.SetStyle(ControlStyles.AllPaintingInWmPaint, True)

    Me.DoubleBuffered = True
    Me.Size = szDownSize

  End Sub

  Private Sub ColorPicker_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    RecalcScreenShotSize()
    'get the blank cursor to make the it dissapear when dragging
    Dim assem As Reflection.Assembly = Me.GetType().Assembly
    Dim my_namespace As String = assem.GetName().Name.ToString()
    Dim mystream As IO.Stream
    Try
      mystream = assem.GetManifestResourceStream(my_namespace & ".Dropper.cur")
      DropperCursor = New Cursor(mystream)

    Catch ex As Exception
      DropperCursor = Cursors.Cross
    End Try
    DrawDropper(Color.Blue)
  End Sub

#End Region 'Initialize

#Region "Properties"

  Private _SelectedColor As Color
  <Category("Appearance EyeDropper")> _
  <Description("Current Color at the Cursor Location")> _
  Public Property SelectedColor() As Color
    Get
      Return _SelectedColor
    End Get
    Set(ByVal value As Color)
      If _SelectedColor <> value Then
        _SelectedColor = value
        RaiseEvent SelectedColorChanging(Me, _SelectedColor)
      End If
    End Set
  End Property

  Private _BorderColor As Color = Color.Blue
  <Category("Appearance EyeDropper")> _
  <Description("Color of the Border")> _
  Public Property BorderColor() As Color
    Get
      Return _BorderColor
    End Get
    Set(ByVal value As Color)
      _BorderColor = value
      Me.Invalidate()
    End Set
  End Property

  Private _ButtonColor As Color = Me.BackColor
  <Category("Appearance EyeDropper")> _
  <Description("Background Color for the Button")> _
  Public Property ButtonColor() As Color
    Get
      Return _ButtonColor
    End Get
    Set(ByVal value As Color)
      _ButtonColor = value
      Me.Invalidate()
    End Set
  End Property

#End Region 'Properties

#Region "Mouse Events"

  Private Sub EyeDropScreen_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown
    If e.Button = Windows.Forms.MouseButtons.Left Then
      Cursor = DropperCursor
      blnGettingPixelColor = True
      Me.Size = szZoomWindowSize
      Me.BringToFront()
      Invalidate()
    End If
  End Sub

  Private Sub EyeDropScreen_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
    If e.Button = Windows.Forms.MouseButtons.Left Then
      GetScreenShot()
    End If
  End Sub

  Private Sub EyeDropScreen_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseUp
    Cursor = Cursors.Default
    blnGettingPixelColor = False
    Me.Size = szDownSize
    DrawDropper(_SelectedColor)

    RaiseEvent SelectedColorChanged(Me, _SelectedColor)

    Invalidate()
  End Sub

#End Region 'Mouse Events

#Region "Screen Capture"

  Sub RecalcScreenShotSize()
    If bmpScreenShot IsNot Nothing Then
      bmpScreenShot.Dispose()
    End If
    bmpScreenShot = New Bitmap(CInt(szZoomWindowSize.Width / sngZoom), CInt(szZoomWindowSize.Height / sngZoom))
  End Sub

  Sub GetScreenShot()
    Dim scrPt As Point = Control.MousePosition
    scrPt.X -= bmpScreenShot.Width / 2
    scrPt.Y -= bmpScreenShot.Height / 2

    Using g As Graphics = Graphics.FromImage(bmpScreenShot)
      g.CopyFromScreen(scrPt, New Point(0, 0), bmpScreenShot.Size)
    End Using

    Me.SelectedColor = bmpScreenShot.GetPixel(bmpScreenShot.Size.Width / 2, bmpScreenShot.Size.Height / 2)

    Refresh()
  End Sub

#End Region 'Screen Capture

#Region "Painting"

  Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
    MyBase.OnPaint(e)
    Dim rr As New Rectangle
    Dim crns As Integer = 0
    If bmpScreenShot IsNot Nothing Then
      e.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor
      e.Graphics.SmoothingMode = SmoothingMode.None
      Try

        If blnGettingPixelColor Then
          crns = 0
          rr.Size = szZoomWindowSize
          Dim centerrect As Rectangle = New Rectangle((szZoomWindowSize.Width / 2) - (sngZoom / 2) + 1, _
              (szZoomWindowSize.Height / 2) - (sngZoom / 2) + 1, sngZoom - 1, sngZoom - 1)
          e.Graphics.DrawImage(bmpScreenShot, 0, 0, szZoomWindowSize.Width, szZoomWindowSize.Height)
          e.Graphics.DrawRectangle(Pens.Black, centerrect)
        Else
          crns = 3
          rr.Size = szDownSize
          e.Graphics.FillRectangle(New SolidBrush(Me.BackColor), New Rectangle(New Point(0, 0), szDownSize))
          e.Graphics.FillPath(New SolidBrush(Me._ButtonColor), GetRectPath(rr, crns))
          e.Graphics.DrawImage(bmpButtonImage, 3, 3)
        End If

      Catch ex As Exception

      End Try
    End If
    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias
    e.Graphics.DrawPath(New Pen(_BorderColor), GetRectPath(rr, crns))
  End Sub

  Private Sub DrawDropper(ByVal TipColor As Color)
    bmpButtonImage = New Bitmap(16, 16)
    Using g As Graphics = Graphics.FromImage(bmpButtonImage)
      g.SmoothingMode = SmoothingMode.AntiAlias
      'Tube Border
      g.DrawLine(Pens.Gray, 0, 15, 0, 13)
      g.DrawLine(Pens.Black, 0, 13, 7, 6)
      g.DrawLine(Pens.Gray, 0, 15, 2, 15)
      g.DrawLine(Pens.Black, 2, 15, 9, 8)

      'Tube Fill
      g.DrawLine(Pens.White, 1, 13, 8, 6)
      g.DrawLine(Pens.Silver, 1, 14, 8, 7)
      g.DrawLine(Pens.Silver, 2, 14, 9, 7)
      g.DrawLine(New Pen(TipColor), 1, 13, 4, 10)
      g.DrawLine(New Pen(TipColor), 1, 14, 5, 10)
      g.DrawLine(New Pen(TipColor), 2, 14, 6, 10)

      'Bulb Hilt
      g.DrawLine(Pens.Black, 6, 3, 12, 9)
      g.DrawLine(Pens.Black, 7, 3, 12, 8)

      'Bulb Border
      g.DrawLine(Pens.Black, 9, 3, 12, 0)
      g.DrawLine(Pens.Black, 12, 0, 14, 0)
      g.DrawLine(Pens.Black, 15, 1, 15, 3)
      g.DrawLine(Pens.Black, 12, 6, 15, 3)

      'Bulb Fill
      g.DrawLine(Pens.Gray, 9, 4, 12, 1)
      g.DrawLine(Pens.White, 10, 4, 13, 1)
      g.DrawLine(Pens.DimGray, 10, 5, 14, 1)
      g.DrawLine(Pens.DimGray, 11, 5, 14, 2)
      g.DrawLine(Pens.Black, 11, 6, 14, 3)
    End Using
  End Sub

  Public Function GetRectPath(ByVal BaseRect As RectangleF, ByVal CornerRadius As Integer) As GraphicsPath

    Dim BorderRect As Rectangle = New Rectangle(0, 0, BaseRect.Width - 2, BaseRect.Height - 2)

    Dim ArcRect As RectangleF
    Dim MyPath As New GraphicsPath()
    If CornerRadius = 0 Then
      MyPath.AddRectangle(BorderRect)
    Else
      With MyPath
        ArcRect = New RectangleF(BorderRect.Location, _
            New SizeF(CornerRadius * 2, CornerRadius * 2))
        ' top left arc
        .AddArc(ArcRect, 180, 90)

        ' top right arc
        ArcRect.X = BorderRect.Right - (CornerRadius * 2)
        .AddArc(ArcRect, 270, 90)

        ' bottom right arc
        ArcRect.Y = BorderRect.Bottom - (CornerRadius * 2)
        .AddArc(ArcRect, 0, 90)

        ' bottom left arc
        ArcRect.X = BorderRect.Left
        .AddArc(ArcRect, 90, 90)

        .CloseFigure()
      End With
    End If

    Return MyPath

  End Function

#End Region 'Painting 

End Class

#End Region 'EyeDropper